﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Text;
using System.Linq.Expressions;
using CoolCode.Data;
using CoolCode.Models;

namespace CoolCode.Services
{
	public abstract class ServiceBase : IService//ITrackService
	{
		private IDataContext _context = null;
		private Func<IDataContext> _createDataContext;
		protected string ConnectionString;

		protected IDataContext Context
		{
			get
			{
				if (_context == null)
					_context = _createDataContext();
				return _context;
			}
		}

		public virtual bool Log { get; set; }

		public ServiceBase()
		//: this(string.Empty)
		{
			_createDataContext = CreateDataContext;
		}

		//public ServiceBase(string connectionString)
		//{
		//    this.connectionString = connectionString;
		//    this.Log = true;
		//    this.Refresh();
		//}

		public ServiceBase(IDataContext dataContext)
		{
			_context = dataContext;
		}

		protected virtual IDataContext CreateDataContext()
		{
			return DataContextProxy.Instance.Provide();
			//if (string.IsNullOrEmpty(connectionString))
			//    db = DataContextFactory.Create();
			//else
			//    db = DataContextFactory.Create(connectionString);
		}

		protected void CreateDataContextFrom(Func<IDataContext> provideDataContext)
		{
			_createDataContext = provideDataContext;
		}

		protected virtual IRepository<T> CreateRepository<T>() where T : class
		{
			return Context.CreateRepository<T>();
		}

		public virtual void Submit()
		{
			Context.SubmitChanges();
		}

		///// <summary>
		///// save program log and submit transation
		///// </summary>
		///// <param name="entity"></param>
		//public virtual void LogAndSubmit(ILog log)
		//{
		//    if (this.Log && log != null)
		//    {
		//        Log entity = new Log
		//        {
		//            From = log.From,
		//            Desc = log.Desc,
		//            Name = log.Name,
		//            Path = log.Path,
		//            Time = log.Time,
		//            Type = log.Type,
		//            User = log.User
		//        };
		//        //Logger.Insert(entity);
		//    }
		//    this.Submit();
		//}

		protected virtual ILoadOption LoadWith<T>(Expression<Func<T, object>> property)
		{
			return Context.LoadOptions.LoadWith<T>(property);
		}
	}


	//public abstract class ServiceBase : ITrackService
	//{
	//    private XDataContext db;

	//    public virtual bool Log { get; set; }

	//    #region Data Access Object

	//    private IRepository<Log> _logger = null;
	//    public IRepository<Log> Logger
	//    {
	//        get
	//        {
	//            if (_logger == null)
	//                _logger = this.CreateRepository<Log>();
	//            return _logger;
	//        }
	//        set
	//        {
	//            _logger = value;
	//        }
	//    }

	//    #endregion

	//    protected string connectionString;

	//    public ServiceBase()
	//        : this(string.Empty)
	//    {

	//    }

	//    public ServiceBase(string connectionString)
	//    {
	//        this.connectionString = connectionString;
	//        this.Log = true;
	//        this.Refresh();
	//    }

	//    //public ServiceBase(XDataContext dataContext)
	//    //{
	//    //    db = dataContext;
	//    //}

	//    public virtual void Refresh()
	//    {
	//        if (string.IsNullOrEmpty(connectionString))
	//            db = DataContextFactory.Create();
	//        else
	//            db = DataContextFactory.Create(connectionString);
	//    }

	//    protected virtual IRepository<T> CreateRepository<T>() where T : class
	//    {
	//        return db.Create<T>();
	//    }

	//    public virtual void Submit()
	//    {
	//        db.SubmitChanges();
	//    }

	//    /// <summary>
	//    /// save program log and submit transation
	//    /// </summary>
	//    /// <param name="entity"></param>
	//    public virtual void LogAndSubmit(Log entity)
	//    {
	//        if (this.Log && entity != null)
	//            Logger.Insert(entity);
	//        this.Submit();
	//    }

	//    private ILoadOption options;

	//    protected virtual  ILoadOption  LoadWith<T>(Expression<Func<T, object>> property)
	//    {  
	//        return (options ?? new LoadOption(db)).LoadWith<T>(property);
	//    }

	//    protected virtual void LoadWith(DataLoadOptions options)
	//    {
	//        db.LoadOptions = options;
	//    }

	//}


	//public class LoadOption<T> : ILoadOption
	//{
	//    private XDataContext db;
	//    DataLoadOptions opt;

	//    public LoadOption(XDataContext context)
	//    {
	//        db = context;
	//        opt = new DataLoadOptions();
	//    }

	//    #region ILoadOption Members

	//    public ILoadOption LoadWith<T>(Expression<Func<T, object>> property)
	//    {
	//        opt.LoadWith<T>(property);
	//        return this;
	//    }

	//    public void EndLoad()
	//    {
	//        db.LoadOptions = opt;
	//    }

	//    #endregion
	//}
}
